﻿using AppServices.User.Dto;
using AutoMapper;
using Domain;
using Domain.Entities;
using Infrastructure.Bases;
using Infrastructure.Models.Others;
using Infrastructure.Options;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using SqlSugar;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;


namespace AppServices.User
{
    public class UserInfoAppService : BaseAppService<UserInfo>
    {
        private readonly ISqlSugarClient _db;
        private readonly BaseRepository<UserInfo> _baseRepository;
        private readonly IMapper _mapper;
        private readonly JwtTokenOption _jwtOption;

        public UserInfoAppService(ISqlSugarClient db, BaseRepository<UserInfo> baseRepository, IMapper mapper, IOptionsMonitor<JwtTokenOption> jwtOption) : base(baseRepository)
        {
            _db = db;
            _baseRepository = baseRepository;
            _mapper = mapper;
            _jwtOption = jwtOption.CurrentValue;
        }

        /// <summary>
        /// 添加用户用例
        /// </summary>
        /// <param name="loginDto"></param>
        /// <returns></returns>
        public async Task<UserInfoOutput> AddUser(UserInfoInput userInfoInput)
        {
            if (await _db.Queryable<UserInfo>().AnyAsync(p => p.UserName== userInfoInput.UserName))
            {
                throw new Exception("用户已存在");
            }
            else
            {
                UserInfo userInfo = _mapper.Map<UserInfo>(userInfoInput);
                await _db.Insertable<UserInfo>(userInfo).ExecuteCommandAsync();
                return _mapper.Map<UserInfoOutput>(userInfo);
            }
        }


        /// <summary>
        /// 登陆用例
        /// </summary>
        /// <param name="loginDto"></param>
        /// <returns></returns>
        public async Task<string> Login(LoginReq loginReq)
        {
            List<UserInfo> userInfos = await _baseRepository.Query(p => p.UserName == loginReq.UserName && p.Pwd == loginReq.Password); ;
            if (userInfos != null && userInfos.Count > 0)
            {
                return await GenerateTokenAsync(userInfos[0]);
            }
            else
            {
                throw new Exception("用户不存在或者密码错误");
            }
        }

        private async Task<string> GenerateTokenAsync(UserInfo userInfo)
        {
            var result = await Task.Run(() =>
            {
                var claims = new[]
                {
                    new Claim("Id",userInfo.Id.ToString()),
                    //new Claim("NickName",user.NickName),
                    new Claim("UserName",userInfo.UserName),
                    //new Claim("UserType",user.UserType),
                    //new Claim("Image",user.Image==null?"":user.Image),
                };
                //需要加密：需要加密key
                //引入：Microsoft.IdentityModel.Tokens
                SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOption.SecurityKey));
                SigningCredentials credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                //引入：System.IdentityModel.Tokens.Jwt
                JwtSecurityToken token = new JwtSecurityToken(
                    issuer: _jwtOption.Issuer,
                    audience: _jwtOption.Audience,
                    claims: claims,
                    expires: DateTime.Now.AddMinutes(10),//10分钟有效
                    notBefore: null,
                    signingCredentials: credentials);

                string res = new JwtSecurityTokenHandler().WriteToken(token);
                return res;
            });
            return result;
        }
    }
}
